/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Model;

import Actors.Actor;
import Actors.CollisionType;
import ElementsProperties.ActorCollisionSensible;
import ElementsProperties.ActorEntranceSensible;
import Floors.WaterFloor;
import Items.Item;
import Stones.Oxyde;
import Stones.Stone;
import Floors.Floor;
import java.awt.image.BufferedImage;
import java.lang.Object;
import java.util.Vector;

/**
 *
 * @author Snowangelic
 */
public class Case {
    Vector<CaseListener> listeners;
    Vector<Actor> actorList;
    Floor floor;
    Stone stone;
    Item item;
    Plateau plate;
    int xIndex;
    int yIndex;
    boolean itemChanged;
    boolean floorChanged;
    boolean stoneChanged;

    public Case(Plateau plate,int xIndex,int yIndex,Floor floor,Stone stone,Item item){
        listeners=new Vector<CaseListener>();
        actorList=new Vector<Actor>();
        this.plate=plate;
        this.floor=floor;
        if(floor!=null)floor.setCase(this);
        this.stone=stone;
        if(stone!=null)stone.setCase(this);
        this.item=item;
        if(item!=null)item.setCase(this);
        this.xIndex=xIndex;
        this.yIndex=yIndex;
    }

    public void addListener(CaseListener listener){
        if(!listeners.contains(listener))
            listeners.add(listener);

        listener.floorChanged(new CaseEvent(this));
        listener.stoneChanged(new CaseEvent(this));
        listener.itemChanged(new CaseEvent(this));
    }
    public void removeListener(CaseListener listener){
        if(listeners.contains(listener))
            listeners.remove(listener);
    }

    public Stone getStone() {
        return this.stone;
    }

    public Item getItem() {
        return this.item;
    }

    public Floor getFloor(){
        return this.floor;
    }


    public void setFloor(Floor newFloor) {
        floor=newFloor;
        newFloor.setCase(this);
        setFloorChanged(true);
    }


    public BufferedImage getFloorImage(){
        floorChanged=false;
        if(floor!=null) return floor.getImage();
        else return EnigmaUtils.TransparentImage.getTransparentImage();
    }

    public void setStone(Stone newStone) {
        this.stone=newStone;
        stone.setCase(this);
        setStoneChanged(true);
    }


    public BufferedImage getStoneImage(){
        stoneChanged=false;
        if(stone!=null) return stone.getImage();
        else return EnigmaUtils.TransparentImage.getTransparentImage();
    }



    public BufferedImage getItemImage(){
        if(item!=null){
            return item.getImage();
        }
        else{
            return EnigmaUtils.TransparentImage.getTransparentImage();
        }
        
    }

  public void updateFloor(long dtime){
        if(floor!=null) floor.update(dtime);
    }

    public void setFloorChanged(Boolean changed){
        if(changed==true)
            for(CaseListener listener : listeners)
                listener.floorChanged(new CaseEvent(this));
    }

    public void updateStone(long dtime){
        if(stone!=null) stone.update(dtime);
    }

    public void setStoneChanged(boolean changed){
        if(changed==true)
            for(CaseListener listener : listeners)
                listener.stoneChanged(new CaseEvent(this));
    }

    public void updateItem(long dtime){
        if(item!=null) item.update(dtime);
    }

    public void setItemChanged(boolean changed){
        if(changed==true)
            for(CaseListener listener : listeners)
                listener.itemChanged(new CaseEvent(this));
    }

    public void removeItem(){
        item = null;
        setItemChanged(true);
    }

    public void removeStone() {
        stone=null;
        setStoneChanged(true);
    }

    public void removeFloor() {
        floor=null;
        setFloorChanged(true);
    }


    public void addItem(Item newItem) {
        item = newItem;
        item.setCase(this);
        setItemChanged(true);

    }

    public void actorEnters(Actor actor){
        actorList.add(actor);
        Vector<Object> componentList=this.getComponentList();
        for(Object o : componentList)
            if(o instanceof ActorEntranceSensible)
               ((ActorEntranceSensible)o).actorEnters(actor);
    }

    public void actorLeaves(Actor actor){
        actorList.remove(actor);
        Vector<Object> componentList=this.getComponentList();
        for(Object o : componentList)
            if(o instanceof ActorEntranceSensible)
               ((ActorEntranceSensible)o).actorLeaves(actor);
    }

    public int getXIndex(){
        return xIndex;
    }

    public int getYIndex(){
        return yIndex;
    }

    public double getFriction(){
        return floor.getFriction();
    }

    public double[] getImpulse(Actor actor){
        double[] impulse=new double[2];
        impulse[0]=0;
        impulse[1]=0;
        if(floor!=null)if(floor.getImpulse(actor)!=null){
            double[] tempImpulse=floor.getImpulse(actor);
            impulse[0]=impulse[0]+tempImpulse[0];
            impulse[1]=impulse[0]+tempImpulse[1];
        }
        if(stone!=null)if(stone.getImpulse(actor)!=null){
            double[] tempImpulse=stone.getImpulse(actor);
            impulse[0]=impulse[0]+tempImpulse[0];
            impulse[1]=impulse[0]+tempImpulse[1];
        }
        if(item!=null)if(item.getImpulse(actor)!=null){
            double[] tempImpulse=item.getImpulse(actor);
            impulse[0]=impulse[0]+tempImpulse[0];
            impulse[1]=impulse[0]+tempImpulse[1];
        }

        return impulse;
    }

    public void upCollision(Actor actor){
        Vector<Object> componentList=this.getComponentList();
        for(Object o : componentList)
            if(o instanceof ActorCollisionSensible)
               ((ActorCollisionSensible)o).actorCollision(new CollisionEvent(actor,this,CollisionType.Up));
    }

    public void downCollision(Actor actor){
        Vector<Object> componentList=this.getComponentList();
        for(Object o : componentList)
            if(o instanceof ActorCollisionSensible)
               ((ActorCollisionSensible)o).actorCollision(new CollisionEvent(actor,this,CollisionType.Down));
    }

    public void leftCollision(Actor actor){
        Vector<Object> componentList=this.getComponentList();
        for(Object o : componentList)
            if(o instanceof ActorCollisionSensible)
               ((ActorCollisionSensible)o).actorCollision(new CollisionEvent(actor,this,CollisionType.Left));
    }

    public void rightCollision(Actor actor){
        Vector<Object> componentList=this.getComponentList();
        for(Object o : componentList)
            if(o instanceof ActorCollisionSensible)
               ((ActorCollisionSensible)o).actorCollision(new CollisionEvent(actor,this,CollisionType.Right));
    }
/*
    public void upLeftCollision(Actor actor){
        if(stone!=null)stone.upLeftCollision(actor);
    }

    public void upRightCollision(Actor actor){
        if(stone!=null)stone.upRightCollision(actor);
    }

    public void downLeftCollision(Actor actor){
        if(stone!=null)stone.downLeftCollision(actor);
    }

    public void downRightCollision(Actor actor){
        if(stone!=null)stone.downRightCollision(actor);
    }
 * */

    public Case getCase(int xIndex,int yIndex){
        return plate.getCase(xIndex, yIndex);
    }

    public Vector<Object> getComponentList(){
        Vector<Object> list=new Vector<Object>();
        if(floor!=null) list.add(floor);
        if(stone!=null) list.add(stone);
        if(item!=null) list.add(item);
        list.addAll(actorList);
        return list;
    }
}
